package org.example.FFMDemon;

import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.util.Optional;

public class foreignDemo {
    //操作内存
    public static MemorySegment memory(char chars ){
        try (Arena arena = Arena.ofConfined()){
            //分配 8 个字节的本地内存
            MemorySegment allocate = arena.allocate(8);
            //写入内存
            // 第一个为 内型 第二个为 字节内存索引 第三个为 值
            allocate.set(ValueLayout.JAVA_CHAR,0,chars );
            // 第一个为 内型 第二个为 字节内存索引
            System.out.println("内存添加:"+ allocate.get(ValueLayout.JAVA_CHAR, 0));
            return allocate;
        }
    }

    public static void stdPrintfTest(Object s){
        try (Arena arena = Arena.ofConfined()) {  // 创建受控内存区域，自动管理资源释放（类似 try-with-resources）
            // 获取本地链接器实例（用于绑定本地函数）
            Linker linker = Linker.nativeLinker();

            // 获取默认符号查找器（通常对应C标准库）
            SymbolLookup symbolLookup = linker.defaultLookup();

            // 查找 C 标准库中的 printf 函数符号
            Optional<MemorySegment> printf = symbolLookup.find("printf");

            // 若未找到符号则抛出异常（确保函数存在）
            MemorySegment printfFunction = printf.orElseThrow(
                    () -> new RuntimeException("找不到 printf 函数符号")
            );

            // 定义函数描述符：返回值类型为 int，参数类型为指针（对应C的 const char*）
            FunctionDescriptor descriptor = FunctionDescriptor.of(
                    ValueLayout.JAVA_INT,       // 返回值类型：int
                    ValueLayout.ADDRESS          // 参数类型：指针（字符串地址）
            );

            // 创建指向 printf 的方法句柄（绑定函数指针与描述符）
            MethodHandle methodHandle = linker.downcallHandle(printfFunction, descriptor);

            // 将Java字符串转换为C格式的UTF-8字符串（自动分配内存并添加\0结尾）
            MemorySegment cString = arena.allocateFrom(s.toString());

            // 调用 printf 函数（传递C字符串地址）
            methodHandle.invoke(cString);  // 等效于C的 printf("你好，java FFM");

        } catch (Throwable e) {  // 捕获所有可能的异常（包括本地调用错误）
            throw new RuntimeException("FFM 调用失败", e);
        }
    }

}
